package com.github.livebase.database;

import android.content.ContentValues;

import com.github.livebase.event.Event;
import com.github.livebase.event.EventBus;
import com.github.livebase.event.EventListener;
import com.github.livebase.util.base.DateUtil;

import java.util.Date;

/**
 * @ClassName StorageOp
 * @description:
 * @author: biao532
 * @create: 2024-02-18 19:28
 * @Version 1.0
 **/

public class StorageOperator implements EventListener {
    public static final long EXPIRE_LASTING = 62474774400000L;

    @Override
    public void onEvent(Event event) {
        if (!Event.isEvent(event, EventBus.EVENT_CHANGE_DATE)) {
            return;
        }
        Date date = event.getAttachObject();
        op.delete(tableName, "expire<?", new String[] {String.valueOf(date.getTime())});
    }

    public static class StorageEntity {
        private String owner;
        private String key;
        private byte[] value;
        private String clazz;
        private long expire;
        private int version;
        public StorageEntity(String owner, String key, int version, byte[] value, String clazz, long expire) {
            this.owner = owner;
            this.key = key;
            this.value = value;
            this.clazz = clazz;
            this.expire = expire;
            this.version = version;
        }

        public String getOwner() {
            return owner;
        }

        public void setOwner(String owner) {
            this.owner = owner;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public byte[] getValue() {
            return value;
        }

        public void setValue(byte[] value) {
            this.value = value;
        }

        public String getClazz() {
            return clazz;
        }

        public void setClazz(String clazz) {
            this.clazz = clazz;
        }

        public long getExpire() {
            return expire;
        }

        public void setExpire(long expire) {
            this.expire = expire;
        }

        public int getVersion() {
            return version;
        }

        public void setVersion(int version) {
            this.version = version;
        }
    }
    private String tableName = "live_storage";
    //  owner(数据所有者), key, version(版本), value, clazz(value 类型), expire(有效期/6089.01.01 00:00:00为永久有效，需定时清除)
    private OperatorHelper op;
    public StorageOperator(OperatorHelper op) {
        this.op = op;
    }

    public StorageEntity get(String key, String owner, int version) {
        return op.select(tableName, new String[]{"value", "clazz", "expire"},
                "where key=? and owner=? and expire>=? and version=?", new String[]{key, owner, String.valueOf(DateUtil.now()), String.valueOf(version)},
                (cu)-> {
                    long expire = cu.getLong(2);
            return new StorageEntity(owner, key, version, cu.getBlob(0), cu.getString(1), expire==EXPIRE_LASTING?-1:expire);
                });
    }

    public void upsert(StorageEntity entity) {
        ContentValues contentValues = new ContentValues();
        contentValues.put("version", entity.version);
        contentValues.put("owner", entity.owner);
        contentValues.put("key", entity.key);
        contentValues.put("value", entity.value);
        contentValues.put("clazz", entity.clazz);
        contentValues.put("expire", entity.expire <= 0?EXPIRE_LASTING:entity.expire);
        op.upsert(tableName, contentValues);
    }

    public boolean exist(String key, String owner, int version) {
        return op.exist(tableName, "key=? and owner=? and expire>=? and version=?", new String[]{
                key, owner, String.valueOf(DateUtil.now()), String.valueOf(version)
        });
    }

    public int delete(String owner) {
        return op.delete(tableName, "owner=?", new String[]{owner});
    }

    public int deleteByKeyPrefix(String prefix, String owner) {
        return op.delete(tableName, "owner=? and key like ?", new String[]{owner, prefix});
    }
    public int delete(String key, String owner) {
        return op.delete(tableName, "key=? and owner=?", new String[]{
                key, owner
        });
    }
}

